package cn.itcast.bos.service.take_delivery.impl;

import cn.itcast.bos.dao.take_delivery.WayBillRepository;
import cn.itcast.bos.domain.take_delivery.WayBill;
import cn.itcast.bos.index.WayBillIndexRepository;
import cn.itcast.bos.service.take_delivery.WayBillService;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.elasticsearch.index.query.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class WayBillServiceImpl implements WayBillService {

    private final static Logger LOG = Logger.getLogger(WayBillServiceImpl.class);
    @Autowired
    private WayBillRepository wayBillRepository;
    @Autowired
    private WayBillIndexRepository wayBillIndexRepository;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Override
    public void save(WayBill model) {
        model.setSignStatus(1);
        WayBill wayBill = wayBillRepository.findByWayBillNum(model.getWayBillNum());
        if (wayBill == null) {
            wayBillRepository.save(model);
            wayBillIndexRepository.save(model);
        } else {
            if (wayBill.getSignStatus() == 1) {
                Integer wid = wayBill.getId();
                BeanUtils.copyProperties(model, wayBill);
                wayBill.setId(wid);
                wayBillRepository.save(wayBill);
                wayBillIndexRepository.save(wayBill);
            } else {
                throw new RuntimeException("运单已发出,无法修改");
            }
        }
    }

    @Override
    public Page<WayBill> showPage(Pageable pageable, WayBill model) {
        if (StringUtils.isBlank(model.getWayBillNum()) && StringUtils.isBlank(model.getRecAddress())
                && StringUtils.isBlank(model.getSendAddress()) && StringUtils.isBlank(model.getWayBillNum())
                && (model.getSignStatus() == null || model.getSignStatus() == 0)) {
            return wayBillRepository.findAll(pageable);
        } else {
            //创建一个多条件查询  boolQuery
            //must 条件必须成立
            //must not 条件必须不成立
            //should 可能成立
            BoolQueryBuilder query = new BoolQueryBuilder();
            //判断是否有某查询字段,创建查询  termQuery 词条查询  wildcard 模糊查询
            if (StringUtils.isNotBlank(model.getWayBillNum())) {
                QueryBuilder queryBuilder = new TermQueryBuilder("wayBillNum", model.getSendProNum());
                query.must(queryBuilder);
            }
            if (StringUtils.isNotBlank(model.getRecAddress())) {
//                如果查询内容很长就查不到:"四川成都双流"
//                QueryBuilder queryBuilder = new WildcardQueryBuilder("recAddress", model.getRecAddress());
//                query.must(queryBuilder);
                //改良
                //情况一:输入"四" 是查询词条一部分,使用模糊匹配词条查询
                QueryBuilder queryBuilder = new WildcardQueryBuilder("recAddress", "*" + model.getRecAddress() + "*");
                //情况二:输入"四川成都双流"是多个词条,进行分词后每个词条匹配查询
                QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(
                        model.getRecAddress()).field("recAddress")
                        .defaultOperator(QueryStringQueryBuilder.Operator.AND);
                //两种情况取一种should
                BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
                boolQueryBuilder.should(queryBuilder);
                boolQueryBuilder.should(queryStringQueryBuilder);
                query.must(boolQueryBuilder);
            }
            if (StringUtils.isNotBlank(model.getSendAddress())) {
//                QueryBuilder queryBuilder = new WildcardQueryBuilder("sendAddress", model.getSendAddress());
//                query.must(queryBuilder);
                //改良
                //情况一:输入"四" 是查询词条一部分,使用模糊匹配词条查询
                QueryBuilder queryBuilder = new WildcardQueryBuilder("sendAddress", "*" + model.getSendAddress() + "*");
                //情况二:输入"四川成都双流"是多个词条,进行分词后每个词条匹配查询
                QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(
                        model.getSendAddress()).field("sendAddress")
                        .defaultOperator(QueryStringQueryBuilder.Operator.AND);
                //两种情况取一种should
                BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
                boolQueryBuilder.should(queryBuilder);
                boolQueryBuilder.should(queryStringQueryBuilder);
                query.must(boolQueryBuilder);

            }
            if (StringUtils.isNotBlank(model.getSendProNum())) {
                QueryBuilder queryBuilder = new TermQueryBuilder("sendProNum", model.getSendProNum());
                query.must(queryBuilder);
            }
            if (model.getSignStatus() != null && model.getSignStatus() != 0) {
                QueryBuilder queryBuilder = new TermQueryBuilder("signStatus", model.getSignStatus());
                query.must(queryBuilder);
            }
            SearchQuery searchQuery = new NativeSearchQuery(query);
            //分页效果
            searchQuery.setPageable(pageable);
            //查询索引库,返回查询集合
            return wayBillIndexRepository.search(searchQuery);
        }
    }

    @Override
    public WayBill findByNum(String wayBillNum) {
        return wayBillRepository.findByWayBillNum(wayBillNum);
    }

    @Override
    public void updateIndex() {
        
        List<WayBill> wayBills = wayBillRepository.findAll();
        elasticsearchTemplate.deleteIndex("bos");
        elasticsearchTemplate.createIndex(WayBill.class);
        elasticsearchTemplate.putMapping(WayBill.class);
        wayBillIndexRepository.save(wayBills);
    }

}
